package com.slipper.common.permit;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class PermitConfiguration implements BeanPostProcessor {
    private final PermitService permitService = new PermitService();
    
    @Bean
    public PermitService permitService() {
        return this.permitService;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> clz = bean.getClass();
        /* 判断此bean是否是controlelr */
        boolean clzHasAnno = clz.isAnnotationPresent(Controller.class);
        boolean clzzHasAnno = clz.isAnnotationPresent(RestController.class);
        if (clzHasAnno || clzzHasAnno) {
            Method[] methods = clz.getDeclaredMethods();
            for (Method method : methods) {
                /* 优先判断某个方法是否有自定义注解 */
                boolean getHasAnno = method.isAnnotationPresent(PermitAll.class);
                if (getHasAnno) {
                    /* 获取此类的一级路径，没有返回空 */
                    String[] classPath = lookupPath(bean.getClass().getAnnotations());
                    String firstPath = classPath != null && classPath.length > 0 ? classPath[0] : "";
                    
                    String[] methodPath = lookupPath(method.getAnnotations());
                    if (methodPath != null) {
                        for (String s : methodPath) {
                            String fullPath = firstPath + s;
                            this.permitService.add(fullPath);
                        }
                    }
                }
            }
        }
        
        return bean;
    }

    private String[] lookupPath(Annotation[] annotations) {
        for (Annotation ann : annotations) {
            Class<?> annType = ann.annotationType();
            // 如果annType与RequestMapping类型一致 或 RequestMapping注释存在于annType上
            if (annType.isAssignableFrom(RequestMapping.class) 
                    || annType.isAnnotationPresent(RequestMapping.class)) {
                return (String[]) AnnotationUtils.getValue(ann);
            }
        }
        
        return null;
    }
}
